You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

60 lines
2.1 KiB

import { getRequestIP } from "h3";
import { getPublicPostCommentContext } from "#server/service/posts";
import { createComment } from "#server/service/post-comments";
import { notifyReplyCommentCreated } from "#server/service/comment-notify";
import { assertUnderRateLimit } from "#server/utils/simple-rate-limit";
import { parsePublicPostCreateCommentBody } from "#server/api/public/comments-create-body";
export default defineEventHandler(async (event) => {
const publicSlug = event.context.params?.publicSlug;
const postSlug = event.context.params?.postSlug;
if (!publicSlug || !postSlug || typeof publicSlug !== "string" || typeof postSlug !== "string") {
throw createError({ statusCode: 400, statusMessage: "无效请求" });
}
const ctx = await getPublicPostCommentContext(publicSlug, postSlug);
if (!ctx) {
throw createError({ statusCode: 404, statusMessage: "未找到" });
}
const viewer = await event.context.auth.getCurrent();
const ip = getRequestIP(event, { xForwardedFor: true }) ?? "unknown";
if (viewer == null) {
assertUnderRateLimit(`comment-post-guest:${ip}`, 20, 15 * 60 * 1000);
} else {
assertUnderRateLimit(`comment-post-user:${viewer.id}`, 60, 15 * 60 * 1000);
}
const body = await readBody<{
parentId?: number | null;
guestDisplayName?: string;
guestEmail?: string;
guestIsAnonymous?: boolean;
body: unknown;
}>(event);
const parsed = parsePublicPostCreateCommentBody(body);
const newCommentId = await createComment({
postId: ctx.id,
ownerUserId: ctx.userId,
parentId: parsed.parentId,
viewer,
guestDisplayName: parsed.guestDisplayName,
guestEmail: parsed.guestEmail,
guestIsAnonymous: parsed.guestIsAnonymous,
body: parsed.body,
});
void notifyReplyCommentCreated({
postId: ctx.id,
postOwnerUserId: ctx.userId,
commentId: newCommentId,
parentId: parsed.parentId,
actorUserId: viewer?.id ?? null,
actorGuestEmail: viewer == null ? (parsed.guestEmail ?? null) : null,
replyBody: parsed.body,
});
return R.success({ id: newCommentId });
});